//
//  LcbCache.m
//  lcb
//
//  Created by lcb on 16/4/29.
//  Copyright © 2016年 lcb. All rights reserved.
//

#import "LcbCache.h"
#import "LcbDiskCache.h"

@interface LcbCache()
{}
@property (copy, readonly) NSString *name;
@property (strong, readonly) LcbDiskCache *diskCache;

- (nullable instancetype)initWithName:(NSString *)name;
- (nullable instancetype)initWithPath:(NSString *)path NS_DESIGNATED_INITIALIZER;
+ (nullable instancetype)cacheWithName:(NSString *)name;
+ (nullable instancetype)cacheWithPath:(NSString *)path;
- (instancetype)init UNAVAILABLE_ATTRIBUTE;
+ (instancetype)new UNAVAILABLE_ATTRIBUTE;

@end

@implementation LcbCache
+ (instancetype)sharedCache {
    return [self sharedCacheWithName:@"LcbCache"];
}
+ (instancetype)sharedCacheWithName:(NSString*)cachename
{
    static LcbCache *cache = nil;
    static dispatch_once_t onceToken;
    __block NSString *tcachename = cachename;
    dispatch_once(&onceToken, ^{
        NSString *cachePath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory,
                                                                   NSUserDomainMask, YES) firstObject];
        cachePath = [cachePath stringByAppendingPathComponent:@"cn.lcb.LcbCache"];
        if (tcachename==nil || tcachename.length==0) {
            tcachename = @"LcbCache";
        }
        cachePath = [cachePath stringByAppendingPathComponent:tcachename];
        cache = [[self alloc] initWithPath:cachePath];
    });
    return cache;
}
- (instancetype) init {
    return [self initWithPath:@""];
}

- (instancetype)initWithName:(NSString *)name {
    if (name.length == 0) return nil;
    NSString *cacheFolder = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject];
    NSString *path = [cacheFolder stringByAppendingPathComponent:name];
    return [self initWithPath:path];
}

- (instancetype)initWithPath:(NSString *)path {
    if (path.length == 0) return nil;
    LcbDiskCache *diskCache = [[LcbDiskCache alloc] initWithPath:path];
    if (!diskCache) return nil;
    NSString *name = [path lastPathComponent];
    self = [super init];
    _name = name;
    _diskCache = diskCache;
    return self;
}

+ (instancetype)cacheWithName:(NSString *)name {
    return [[LcbCache alloc] initWithName:name];
}

+ (instancetype)cacheWithPath:(NSString *)path {
    return [[LcbCache alloc] initWithPath:path];
}

- (BOOL)containsObjectForKey:(NSString *)key {
    return [_diskCache containsObjectForKey:key];
}

- (void)containsObjectForKey:(NSString *)key withBlock:(void (^)(NSString *key, BOOL contains))block {
    if (!block) return;
    [_diskCache containsObjectForKey:key withBlock:block];
    
}

- (id<NSCoding>)objectForKey:(NSString *)key {
    id<NSCoding> object = [_diskCache objectForKey:key];
    return object;
}

- (void)objectForKey:(NSString *)key withBlock:(void (^)(NSString *key, id<NSCoding> object))block {
    if (!block) return;
    [_diskCache objectForKey:key withBlock:block];
}

- (void)setObject:(id<NSCoding>)object forKey:(NSString *)key {
    [_diskCache setObject:object forKey:key];
}

- (void)setObject:(id<NSCoding>)object forKey:(NSString *)key withBlock:(void (^)(void))block {
    [_diskCache setObject:object forKey:key withBlock:block];
}

- (void)removeObjectForKey:(NSString *)key {
    [_diskCache removeObjectForKey:key];
}

- (void)removeObjectForKey:(NSString *)key withBlock:(void (^)(NSString *key))block {
    [_diskCache removeObjectForKey:key withBlock:block];
}

- (void)removeAllObjects {
    [_diskCache removeAllObjects];
}

- (void)removeAllObjectsWithBlock:(void(^)(void))block {
    [_diskCache removeAllObjectsWithBlock:block];
}

- (void)removeAllObjectsWithProgressBlock:(void(^)(int removedCount, int totalCount))progress
                                 endBlock:(void(^)(BOOL error))end {
    [_diskCache removeAllObjectsWithProgressBlock:progress endBlock:end];
    
}

- (NSString *)description {
    if (_name) return [NSString stringWithFormat:@"<%@: %p> (%@)", self.class, self, _name];
    else return [NSString stringWithFormat:@"<%@: %p>", self.class, self];
}

@end
